package com.yimi.policyservice.service.impl;

import com.yimi.policyservice.common.expetion.ApiException;
import com.yimi.policyservice.dto.enums.DataPermissionEnum;
import com.yimi.policyservice.dto.policyaddr.*;
import com.yimi.policyservice.entity.base.policy.PolicyAccfund;
import com.yimi.policyservice.entity.base.policy.PolicyAddr;
import com.yimi.policyservice.entity.base.policy.PolicyDatum;
import com.yimi.policyservice.entity.base.policy.PolicySocial;
import com.yimi.policyservice.entity.base.system.SysUser;
import com.yimi.policyservice.repository.PolicyAccfundRepository;
import com.yimi.policyservice.repository.PolicyAddressRepository;
import com.yimi.policyservice.repository.PolicyDatumRepository;
import com.yimi.policyservice.repository.PolicySocialRepository;
import com.yimi.policyservice.service.PolicyAddrService;
import com.yimi.policyservice.service.UserDataPermissionService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author jack
 */
@Service
public class PolicyAddrServiceImpl implements PolicyAddrService {

    @Autowired
    PolicySocialRepository policySocialRepository;

    @Autowired
    PolicyAddressRepository policyAddressRepository ;

    @Autowired
    PolicyAccfundRepository policyAccfundRepository ;

    @Autowired
    PolicyDatumRepository policyDatumRepository ;

    @Autowired
    UserDataPermissionService userDataPermissionService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PolicyAddr create(Policy4Create bean, SysUser user) {
        PolicyAddr policyAddr = policyAddressRepository.findFirstByAddrName(bean.getAddr().getAddrName());


        if(policyAddr!=null){
            throw  new ApiException(400,"参保地名称已存在！");
        }

        PolicySoical4Create soical4Create = bean.getSocial();
        PolicyAccfund4Create accfund4Create = bean.getAccfund();
        boolean socialed =soical4Create != null &&
                (StringUtils.isNotBlank(soical4Create.getZyTbCycleCode()) ||
                        StringUtils.isNotBlank(soical4Create.getJyTbCycleCode())
                );
        boolean accfunded =accfund4Create != null &&
                (StringUtils.isNotBlank(accfund4Create.getZyTbCycleCode()) ||
                        StringUtils.isNotBlank(accfund4Create.getJyTbCycleCode())
                );

        if(!socialed && !accfunded){
            throw  new ApiException(400,"信息不全！");
        }
        policyAddr = new PolicyAddr();
        BeanUtils.copyProperties(bean.getAddr(),policyAddr);
        policyAddr.setCreateId(user.getId());
        policyAddr.setCreateTime(new Date());
        policyAddr.setUpdateId(user.getId());
        policyAddr.setUpdateTime(new Date());
        policyAddr.setSocialed(socialed);
        policyAddr.setAccfunded(accfunded);
        policyAddr.setCreateName(user.getName());
        policyAddressRepository.save(policyAddr);
        PolicySocial policySocial = new PolicySocial();
        PolicyAccfund policyAccfund = new PolicyAccfund();
        if(socialed){
            //插入权限，存在则不添加（能添加或者修改，证明有权限）
            userDataPermissionService.addDataPermission(user.getId(),policyAddr.getId(), DataPermissionEnum.SOCIALADDR.getValue());
            BeanUtils.copyProperties(soical4Create,policySocial);
            policySocial.setCreateId(user.getId());
            policySocial.setCreateTime(new Date());
            policySocial.setUpdateId(user.getId());
            policySocial.setUpdateTime(new Date());
            policySocial.setPolicyAddrId(policyAddr.getId());
            policySocialRepository.save(policySocial);
        }
        if(accfunded){
            //插入权限，存在则不添加（能添加或者修改，证明有权限）
            userDataPermissionService.addDataPermission(user.getId(),policyAddr.getId(), DataPermissionEnum.ACCFUNDADDR.getValue());
            BeanUtils.copyProperties(accfund4Create,policyAccfund);
            policyAccfund.setUpdateId(user.getId());
            policyAccfund.setUpdateTime(new Date());
            policyAccfund.setPolicyAddrId(policyAddr.getId());
            policyAccfund.setCreateId(user.getId());
            policyAccfund.setCreateTime(new Date());
            policyAccfundRepository.save(policyAccfund);
        }
        List<PolicyDatum4Create>  policyDatum4Creates = bean.getDataNums();
        if(policyDatum4Creates == null){
            return  policyAddr;
        }
        for(PolicyDatum4Create data4Create : policyDatum4Creates){
            PolicyDatum policyDatum = new PolicyDatum();
            BeanUtils.copyProperties(data4Create,policyDatum);
            policyDatum.setCreateId(user.getId());
            policyDatum.setCreateTime(new Date());
            policyDatum.setUpdateId(user.getId());
            policyDatum.setPolicyAddrId(policyAddr.getId());
            if(policyDatum.getPolicyType()==0){
                policyDatum.setPolicyId(policySocial.getId());
            }else{
                policyDatum.setPolicyId(policyAccfund.getId());
            }
            policyDatum.setUpdateTime(new Date());
            policyDatumRepository.save(policyDatum);
        }
        return policyAddr;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        policyAddressRepository.deleteById(id);
        policyDatumRepository.deleteByAddrId(id);
        policyAccfundRepository.deleteByAddrId(id);
        policySocialRepository.deleteByAddrId(id);
    }


    @Override
    public Policy4GetPut getOne(String id) {
        PolicyAddr policyAddr = policyAddressRepository.findById(id).get();
        if(policyAddr == null){
            throw  new ApiException(404,null);
        }else{
           Policy4GetPut get = new Policy4GetPut();
           get.setAddr(policyAddr);
           if(policyAddr.getSocialed()){
               get.setSocial(policySocialRepository.findOneByPolicyAddrId(id));
           }else{
               get.setSocial(new PolicySocial());
           }
           if(policyAddr.getAccfunded()){
               get.setAccfund(policyAccfundRepository.findOneByPolicyAddrId(id));
           }else{
               get.setAccfund(new PolicyAccfund());
           }

           List<PolicyDatum> datumList = policyDatumRepository.findByPolicyAddrId(id);
           get.setDatumList(datumList);
           return  get ;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysUser loginUser, Policy4GetPut bean) {
        PolicyAddr policyAddr = policyAddressRepository.findById(bean.getAddr().getId()).get();
        BeanUtils.copyProperties(bean.getAddr(),policyAddr);
        Date now = new Date();
        policyAddr.setUpdateTime(now);
        policyAddr.setUpdateId(loginUser.getId());
        policyAddressRepository.save(policyAddr);
        PolicySocial soical4Create = bean.getSocial();
        PolicyAccfund accfund4Create = bean.getAccfund();
        boolean socialed =soical4Create != null &&
                (StringUtils.isNotBlank(soical4Create.getZyTbCycleCode()) ||
                        StringUtils.isNotBlank(soical4Create.getJyTbCycleCode())
                );
        boolean accfunded =accfund4Create != null &&
                (StringUtils.isNotBlank(accfund4Create.getZyTbCycleCode()) ||
                        StringUtils.isNotBlank(accfund4Create.getJyTbCycleCode())
                );
        if(!socialed && !accfunded){
            throw  new ApiException(400,"信息不全！");
        }
            PolicySocial policySocial =  null ;
        if(StringUtils.isNotBlank(bean.getSocial().getId()) || socialed){
            if(StringUtils.isNotBlank(bean.getSocial().getId())){
                policySocial = policySocialRepository.findById(bean.getSocial().getId()).get();
            }else{
                policySocial = new PolicySocial();
            }
            BeanUtils.copyProperties(bean.getSocial(),policySocial);
            policyAddr.setSocialed(true);
            policySocial.setPolicyAddrId(policyAddr.getId());
            policySocial.setUpdateTime(now);
            policySocial.setUpdateId(loginUser.getId());
            policySocialRepository.save(policySocial);
        }
        PolicyAccfund policyAccfund = null ;
        if(StringUtils.isNotBlank(accfund4Create.getId()) || accfunded ) {
            policyAddr.setAccfunded(true);
            if(StringUtils.isNotBlank(accfund4Create.getId())){
                policyAccfund = policyAccfundRepository.findById(bean.getAccfund().getId()).get();
            }else{
                policyAccfund = new PolicyAccfund();
            }
            BeanUtils.copyProperties(bean.getAccfund(),policyAccfund);
            policyAccfund.setPolicyAddrId(policyAddr.getId());
            policyAccfund.setUpdateTime(now);
            policyAccfund.setUpdateId(loginUser.getId());
            policyAccfundRepository.save(policyAccfund);
        }
        List<String> ids = new ArrayList<>();
        for(PolicyDatum datum : bean.getDatumList()){
            //新增的
            if(StringUtils.isBlank(datum.getId())){
                datum.setCreateTime(now);
                datum.setCreateId(loginUser.getId());
                datum.setPolicyAddrId(policyAddr.getId());
                if(datum.getPolicyType()==0 && socialed){
                    datum.setPolicyId(policySocial.getId());
                }
                if(datum.getPolicyType()==1 && accfunded){
                    datum.setPolicyId(policyAccfund.getId());
                }
            }
            datum.setUpdateTime(now);
            datum.setUpdateId(loginUser.getId());
        }
        policyDatumRepository.saveAll(bean.getDatumList());
        for(PolicyDatum datum : bean.getDatumList()){
            ids.add(datum.getId());
        }
        if(ids.isEmpty()){
            policyDatumRepository.deleteByAddrId(policyAddr.getId());
        }else{
            policyDatumRepository.deleteByIdNotIn(bean.getAddr().getId(),ids);
        }

        if(!socialed){
            policyDatumRepository.deleteByAddrIdAndType(policyAddr.getId(),0);
        }
        if(!accfunded){
            policyDatumRepository.deleteByAddrIdAndType(policyAddr.getId(),1);
        }

    }


    @Override
    public List<PolicyAddr> findAll() {
        return policyAddressRepository.findAll();
    }

    @Override
    public List<PolicyAddr>findAllByPermission(String userId,List<Integer> permissionTypes){
        return policyAddressRepository.findAllByPermission(userId,permissionTypes);
    }

    @Override
    public List<PolicyAddr> findByType(int type) {
         if(type == 0 ){
             return  policyAddressRepository.findSocialAddr();
         }else{
             return policyAddressRepository.findAccfundAddr();
         }
    }


    @Override
    public boolean checkUse(List<String> ids) {
       return policyAddressRepository.countByUseIds(ids) == 0;
    }
}
